package test;


import java.lang.reflect.Array;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * Class LangUtils definition.
 *
 * @author Qaohao<qaohao@foxmail.com>
 * @version 1.0
 * @since 2017-02-09 17:12
 */
public interface LangUtils {
    Function<Object, Object> collectionRandomGet = object -> {
        if (object instanceof Collection) {
            Object values[] = ((Collection) object).toArray();
            return values[random(values.length - 1)];
        } else if (object.getClass().isArray()) {
            return Array.get(object, random(Array.getLength(object) - 1));
        } else {
            return object;
        }
    };

    static int unixtime() {
        return (int) (System.currentTimeMillis() / 1000);
    }

    static int random(int max) {
        return random(0, max);
    }

    static int random(int min, int max) {
        if (max < min) {
            throw new IllegalArgumentException("[IllegalArgument]max should big than min.");
        } else if (max == min) {
            return min;
        } else {
            return min + (int) (Math.round((max - min) * Math.random()));
        }
    }

    static <T> List<T> shuffleList(List<T> list) {
        List<T> newList = new ArrayList<>();
        newList.addAll(list);
        Collections.shuffle(newList);
        return newList;
    }

    static String defaultIfNull(String s) {
        return LangUtils.isEmpty(s) ? Global.EMPTY_STR : s;
    }

    static String defaultIfNull(String s, String def) {
        if (LangUtils.isEmpty(s)) {
            return def;
        }
        return s;
    }

    static <T> T defaultIfNull(T t, T def) {
        return t == null ? def : t;
    }

    static <T> T[] asArray(T... t) {
        return t;
    }

    static boolean isEmpty(String str) {
        return (str == null || "".equals(str.trim()));
    }

    static boolean isEmpty(Collection c) {
        return c == null || c.isEmpty();
    }

    static boolean isEmpty(Map m) {
        return m == null || m.isEmpty();
    }

    static <T> boolean isEmpty(T[] t) {
        return t == null || t.length == 0;
    }

    static boolean notEmpty(String str) {
        return !(str == null || "".equals(str.trim()));
    }

    static boolean notEmpty(Collection c) {
        return c != null && !c.isEmpty();
    }

    static boolean notEmpty(Map m) {
        return m != null && !m.isEmpty();
    }

    static <T> boolean notEmpty(T[] t) {
        return t != null && t.length > 0;
    }

    static <T> List<T> addToList(List<T> destList, T o) {
        if (notEmpty(destList)) {
            destList.add(o);
            return destList;
        } else {
            return Arrays.asList(o);
        }
    }

    /**
     * 对字符串进行正则匹配。<code>str</code>或者<code>pattern</code>为空时，返回<code>false</code>
     * ，如果结果匹配不上，返回<code>false</code>，匹配成功返回<code>true</code>。
     * <p>
     * 例如：<br>
     * <li>chkFmt(null, null) = false</li>
     * <li>chkFmt("abc","^\\d+$") = false</li>
     * <li>chkFmt("1232","^\\d+$") = true</li>
     *
     * @param str 待检测字符串
     * @param pattern 正则表达式
     * @return 匹配结果
     */
    static boolean chkFmt(String str, String pattern) {
        if (LangUtils.isEmpty(str) || LangUtils.isEmpty(pattern)) {
            return false;
        } else {
            try {
                Pattern regex = Pattern.compile(pattern);
                Matcher matcher = regex.matcher(str);
                return matcher.matches();
            } catch (Exception e) {
                return false;

            }
        }
    }

    static Object[] toArray(Object... objects) {
        return objects;
    }

    static void clear(Collection... collections) {
        Optional.ofNullable(collections).ifPresent(cc -> Stream.of(cc).forEach(c -> c.clear()));
    }

    static void clear(Map... maps) {
        Optional.ofNullable(maps).ifPresent(mm -> Stream.of(mm).forEach(m -> m.clear()));
    }

    /**
     * 转化十六进制编码为字符串
     */
    static String hex2str(String s) {
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                return null;
            }
        }
        try {
            s = new String(baKeyword, Global.ENCODING);//UTF-16le:Not
        } catch (Exception e1) {
            return null;
        }
        return s;
    }

    static String urlencode(String arg) {
        try {
            return URLEncoder.encode(arg, Global.ENCODING);
        } catch (Exception e) {
            return arg;
        }
    }

    static String urldecode(String arg) {
        try {
            if (arg.indexOf(" ") == -1) {
                return URLDecoder.decode(arg, Global.ENCODING);
            }
            return arg;
        } catch (Exception e) {
            return arg;
        }
    }

    static String mapget(Map<String, List<String>> map, String key) {
        List<String> value = map.get(key);
        if (LangUtils.notEmpty(value)) {
            return value.get(0);
        }
        return null;
    }

    static <T> T newInstance(Class<T> clazz) {
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
